package com.engr.springbooteasypoi.thread;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author : liuYanXin
 * @Description : 死锁
 * @Date : 2020-03-26
 */
public class DeadLock {

    public static void main(String[] args) {
        DeadLockRisk risk = new DeadLockRisk();
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 10, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
        Mythread mythread1 = new Mythread(risk, 1, 2);
        Mythread mythread2 = new Mythread(risk, 3, 4);
        Mythread mythread3 = new Mythread(risk, 5, 6);
        Mythread mythread4 = new Mythread(risk, 7, 8);
        poolExecutor.execute(mythread1);
        poolExecutor.execute(mythread2);
        poolExecutor.execute(mythread3);
        poolExecutor.execute(mythread4);
        poolExecutor.shutdown();
    }
}

class Mythread extends Thread {

    private DeadLockRisk risk;
    private int a, b;

    Mythread(DeadLockRisk risk, int a, int b) {
        this.risk = risk;
        this.a = a;
        this.b = b;
    }

    @Override
    public void run() {
        risk.read();
        risk.write(a, b);
    }
}

class DeadLockRisk {

    private static class Resource {

        public int value;
    }

    private Resource resourceA = new Resource();
    private Resource resourceB = new Resource();

    public int read() {
        synchronized (resourceA) {
            System.out.println("read():" + Thread.currentThread().getName() + "获取了resourceA的锁！");
            synchronized (resourceB) {
                System.out.println("read():" + Thread.currentThread().getName() + "获取了resourceB的锁！");
                return resourceB.value + resourceA.value;
            }
        }
    }

    public void write(int a, int b) {
        synchronized (resourceB) {
            System.out.println("write():" + Thread.currentThread().getName() + "获取了resourceA的锁！");
            synchronized (resourceA) {
                System.out.println("write():" + Thread.currentThread().getName() + "获取了resourceB的锁！");
                resourceA.value = a;
                resourceB.value = b;
            }
        }
    }
}